package butines.game;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import butines.core.Game;
import butines.core.GameContainer;
import butines.core.GameContext;
import butines.core.GameSystem;
import butines.core.Image;
import butines.core.ImageSheet;
import butines.core.Input;
import butines.core.Sprite;
import butines.core.game.GameEntity;
import butines.core.game.GameEntityManager;
import butines.core.game.MessageDispatcher;
import butines.core.game.lqdb.LocalityQueryFacility;
import butines.core.game.util.ImageHelper;
import butines.game.state.StayState;
import butines.game.weapon.SwordWeapon;

public class MainTest implements Game {

	private static MessageDispatcher messageDispatcher;
	private static GameEntityManager gameEntityManager;
	private static LocalityQueryFacility localityQueryFacility;
	
	public static void dispatch(Enum<?> type, GameEntity sender, GameEntity receiver, float delay, Object ... args) {
		messageDispatcher.dispatch(type, sender, receiver, delay, args);
	}
	
	private GameContext ctx;
	private Unit unit;
	private Unit enemy;
	
	private Terrain terrain;
	private ScrollView scrollView;
	
	private Sprite cursorArrow;

	private List<Unit> units = new ArrayList<Unit>();
	
	public void init(GameContext ctx) {
		this.ctx = ctx;
		

		Image iFootman = new Image("datas/unit/footman.png");
		iFootman = ImageHelper.getInstance().createIsometricImage(iFootman, 8);
		
		Image iArcher = new Image("datas/unit/elven_archer.png");
		iArcher = ImageHelper.getInstance().createIsometricImage(iArcher, 8);
		
		ImageSheet isArcher = new ImageSheet(iArcher, 72, 72);
		
		ImageSheet isFootman = new ImageSheet(iFootman, 72, 72);
		//TODO: ANIMAO POSATAQUE
		unit = new Unit();
		unit.setRadius(12);
		unit.setSprite(new Sprite(isArcher));
		unit.getSprite().addAnimation("stay", 0, 0);
		unit.getSprite().addAnimation("walk", .7f, 1, 2, 0, 3, 4, 0);
		unit.getSprite().addAnimation("attack", .3f, 5, 6);
//		unit.setSprite(new Sprite(isFootman));
//		unit.getSprite().addAnimation("stay", 0, 0);
//		unit.getSprite().addAnimation("walk", .7f, 1, 2, 0, 3, 4, 0);
//		unit.getSprite().addAnimation("attack", .4f, 5, 6, 7, 8);
		unit.setSpriteOffsetY(-8);
		unit.setSpriteNumAngles(8);
		unit.getPosition().set(120, 60);
		unit.getStateMachine().changeState(StayState.getInstance());
		unit.setWeapon(new SwordWeapon(3, 92, .7f));
		unit.setMaxSpeed(2.25f);
		
		enemy = new Unit();
		enemy.setRadius(8);
		enemy.setSprite(new Sprite(isFootman));
		enemy.getSprite().addAnimation("stay", 0, 0);
		enemy.getSprite().addAnimation("walk", .7f, 1, 2, 0, 3, 4, 0);
		enemy.getSprite().addAnimation("attack", .3f, 5, 6, 7, 8);
		enemy.setSpriteOffsetY(-8);
		enemy.setSpriteNumAngles(8);
		enemy.getPosition().set(80, 60);
		enemy.getStateMachine().changeState(StayState.getInstance());
		
		units.add(unit);
		units.add(enemy);
		
		cursorArrow = new Sprite(new ImageSheet(new Image("arrow.png"), 128, 128));
		cursorArrow.addAnimation("default", .5f, 0, 1, 2, 3, 4);
		
		ctx.setCursor(cursorArrow);
		
		ImageSheet tileSet = new ImageSheet(new Image("summer.png"), 32, 32);
		terrain = new Terrain(tileSet, 10, 10);
		terrain.init();
		
		terrain.setTile(6, 3, 53);
		terrain.getTile(6, 3).setWalkable(false);
		
		terrain.setTile(6, 2, 53);
		terrain.getTile(6, 2).setWalkable(false);
		
		terrain.setTile(6, 4, 53);
		terrain.getTile(6, 4).setWalkable(false);
		
		scrollView = new ScrollView();
		scrollView.setScreen(ctx.getScreenWidth(), ctx.getScreenHeight());
		scrollView.setView(0, 0, ctx.getScreenWidth(), ctx.getScreenHeight());
		scrollView.setInner(terrain.getWidth(), terrain.getHeight());
		
		gameEntityManager = new GameEntityManager();
		messageDispatcher = new MessageDispatcher();
		
	}

	public void destroy(GameContext ctx) {
		
	}

	public void update(GameContext ctx, float tpf) {
		messageDispatcher.dispatchDelayedMessages();
		
		enemy.update(tpf);
		unit.update(tpf);
		unit.enforceNonPenetrationContraint(units);
		for (Tile t: terrain.getGrid()) {
			if (!t.isWalkable()){
				unit.enforceNonPenetrationContraint(t);
			}
		}
		scrollView.update(ctx, tpf);
	}

	public void render(GameContext ctx, Graphics2D g) {
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, ctx.getScreenWidth(), ctx.getScreenHeight());
				
		float x = scrollView.getOffsetX();
		float y = scrollView.getOffsetY();
		int w = scrollView.getViewWidth();
		int h = scrollView.getViewHeight();
		
		Graphics2D snip = scrollView.createGraphics(g);
		
		terrain.draw(snip, x, y, w, h);
		
		unit.draw(snip, x, y);
		
		enemy.draw(snip, x, y);
		
//		unit.drawHealthBar(snip, x, y);
//		unit.drawCooldownBar(snip,x, y);
//		
//		enemy.drawHealthBar(snip, x, y);
//		enemy.drawCooldownBar(snip, x, y);
		
//		float a = unit.getPosition().x;
//		float b = unit.getPosition().y;
//		float r = unit.getRadius();
//		g.drawOval(Math.round(a - x - r), Math.round(b - y - r), Math.round(r*2), Math.round(r*2));
		
		snip.dispose();
		//g.drawString(scrollView.getOffsetX() + ", " +scrollView.getOffsetY(), 0, 100);
	}

	public static void main(String[] args) {
		GameContainer gameContainer = GameSystem.getGameContainer();
		gameContainer.setDisplayMode(320, 240, 32);
		gameContainer.setFullScreen(false);
		gameContainer.setTargetFps(60);
		gameContainer.start(new MainTest());
	}

	public void onKey(int keyCode, boolean pressed, float tpf) {
		if (Input.KEY_ESC == keyCode) {
			ctx.exit();
		}
	}

	public void onButton(int x, int y, int button, boolean pressed, float tpf) {
		if (button == Input.BUTTON_1 && pressed) {
			unit.attack(enemy);
		}
		if (button == Input.BUTTON_3 && pressed) {
			float viewX = scrollView.toViewX(x);
			float viewY = scrollView.toViewY(y);
			unit.move(viewX, viewY);
		}
	}

	public void onMove(int x, int y, int dx, int dy, float tpf) {
		// TODO Auto-generated method stub
		
	}
	
}
